package com.game.core.net.common;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.game.core.net.message.AbstractCustomizeMessage;

public class GlobalSessionCache
{
	private static Logger logger = LoggerFactory.getLogger(GlobalSessionCache.class);
	private static Map<Integer, ConcurrentHashMap<Long, RemoteNode>> serverSessionsMap = new HashMap<Integer, ConcurrentHashMap<Long, RemoteNode>>();

	public boolean registSession(int serverType, long sessionId,
			RemoteNode session)
	{
		findSessionMap(serverType).put(sessionId, session);
		return true;
	}

	private ConcurrentHashMap<Long, RemoteNode> findSessionMap(int serverType)
	{
		ConcurrentHashMap<Long, RemoteNode> sessionMap = serverSessionsMap
				.get(serverType);
		if (sessionMap == null)
		{
			sessionMap = new ConcurrentHashMap<Long, RemoteNode>();
			serverSessionsMap.put(serverType, sessionMap);
		}
		return sessionMap;
	}

	public int getSessionCount(int serverType)
	{
		return findSessionMap(serverType).size();
	}

	public RemoteNode getSessionById(int serverType, long sessionId)
	{
		return findSessionMap(serverType).get(sessionId);
	}

	public RemoteNode removeSession(int serverType, long sessionId)
	{
		return findSessionMap(serverType).remove(sessionId);
	}

	public boolean sendMessage(int serverType, long sessionId,
			AbstractCustomizeMessage message, ISendMessageInterceptor interceptor)
	{
		RemoteNode session = findSessionMap(serverType).get(sessionId);
		if (interceptor != null
				&& !interceptor.before(serverType, message, session))
			return false;
		if (session == null || !session.isConnected())
			return false;

		try
		{
			session.writeAndFlush(message);
			if (interceptor != null)
				interceptor.after(serverType, message, session);
		} catch (Exception e)
		{
//			e.printStackTrace();
			logger.error("Exception err={}",e.toString());
			if (interceptor != null)
				interceptor.onException(serverType, message, session, e);
		}
		return true;
	}

	public void broadcastMessage(int serverType, AbstractCustomizeMessage message)
	{
		for (RemoteNode session : findSessionMap(serverType).values())
		{
			if (session.isConnected())
				session.writeAndFlush(message);
		}
	}

	// *********************************************//
	private final static GlobalSessionCache _instance = new GlobalSessionCache();

	public final static GlobalSessionCache getGlobalInstance()
	{
		return _instance;
	}
}
